#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/mutex.h>

static void show_entry(struct module *mod)
{
	printk(KERN_INFO "%s\n",
			mod->name);
}

/* should be called with mutex held */
static void __show_modules(void)
{
	struct module *mod;

	list_for_each_entry(mod, *(&THIS_MODULE->list.prev), list) {
		/* looks like that we should check
		 * if module state is MODULE_STATE_LIVE
		 * before doing any manipulations
		 *  -- refer to linux/module.h (try_module_get function)
		 */
		if (try_module_get(mod)) {
			show_entry(mod);
			module_put(mod);
		}
	}

}

static void show_modules(void)
{
	/* refer to kernel/module.c about that */
	mutex_lock(&module_mutex);
	__show_modules();
	mutex_unlock(&module_mutex);
}


static int __init lsmod_init(void)
{
	/* register sysfs entry, so we can use it to dump modules status */
	
	/* FIXME: omg, one-shoot thing */
	show_modules();
	return 0;
}

static void __exit lsmod_exit(void)
{

}

module_init(lsmod_init);
module_exit(lsmod_exit);

MODULE_LICENSE("GPL");
